package cqrtplm.aop;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.hustcad.plm.pdm.common.service.TyplmObjsRenameService;
import com.hustcad.plm.pdm.common.service.search.TyplmCommonSearchService;
import com.hustcad.plm.pdm.defaultvalue.TyplmDefaultValueService;
import com.hustcad.plm.pdm.file.model.dto.UploadFileDTO;
import com.hustcad.plm.pdm.folder.model.vo.SubfolderVO;
import com.hustcad.plm.pdm.folder.model.vo.SubfolderWebVO;
import com.hustcad.plm.pdm.folder.service.TyplmSubFolderLinkService;
import com.hustcad.plm.pdm.iba.service.TyplmAttributeValueService;
import com.hustcad.plm.pdm.lifestage.service.TyplmLifecycleTemplateService;
import com.hustcad.plm.pdm.middle.partbom.service.TyplmPdmPartService;
import com.hustcad.plm.pdm.partbom.dto.InsertPartDTO;
import com.hustcad.plm.pdm.partbom.dto.ModifyPartDTO;
import com.hustcad.plm.pdm.partbom.dto.SimilarCreateDTO;
import com.hustcad.plm.pdm.partbom.service.TyplmPartService;
import com.hustcad.plm.pdm.partbom.vo.PdmPartInfoVO;
import com.hustcad.plm.pdm.partbom.vo.TyPartAllVO;
import com.hustcad.plm.pdm.type.service.TyplmTypeService;
import com.ty.basic.constant.TableTypeConstrant;
import com.ty.basic.entity.IdentifierEntity;
import com.ty.basic.entity.lifecycle.LifeCycleTemplateDO;
import com.ty.basic.entity.part.PartMasterDO;
import cqrtplm.common.CommonService;
import cqrtplm.constant.RTErrorCodeEnum;
import cqrtplm.constant.RTPlmConstant;
import cqrtplm.dto.ClassificationDTO;
import cqrtplm.dto.FlexibleMatchDTO;
import cqrtplm.dto.GenerateDescriptionRuleDto;
import cqrtplm.entity.CodeDrawingDO;
import cqrtplm.entity.CodeMaterialDO;
import cqrtplm.entity.ObjectStorageDO;
import cqrtplm.entity.RtCertBaseCertDO;
import cqrtplm.mapper.*;
import cqrtplm.service.CodeSequenceService;
import cqrtplm.service.ObjectStorageService;
import cqrtplm.service.RTAttributeCardService;
import cqrtplm.service.RTClassificationService;
import cqrtplm.util.SequenceGenerator;
import cqrtplm.vo.DescriptionVO;
import cqrtplm.vo.PDFProjectVO;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.util.*;
import java.util.stream.Collectors;

@Aspect
@Component
@Slf4j
public class CQRTTyplmPartAOP {
    private static final String PATTERN_CODE_TYPE = "ty.inteplm.part.CTyPart|PatternCode";
    private static final String MATERIAL_CODE_TYPE = "ty.inteplm.part.CTyPart|MaterialCode";
    private static final String STANDARD_TYPE = "ty.inteplm.part.CTyPart|Standard";
    private static final String EBOM_NUM_TYPE = "ty.inteplm.part.CTyPart|EBOM_NUM";
    private static final String PRODUCT_SPECTRUM_TYPE = "ty.inteplm.part.CTyPart|" + RTPlmConstant.PARTTYPE;

    private static final String PATTERN_CODE_DESCRIPTION_KEY = "PatternCodeDescription";
    private static final String MATERIAL_CODE_DESCRIPTION_KEY = "MaterialCodeDescription";
    private static final String DESCRIPTION_KEY = "Description";
    private static final String DEV_CODE_KEY = "devCode";
    private static final String PRODUCT_TYPE_KEY = "productType";
    private static final String PATTERN_CODE_KEY = "PatternCode";
    private static final String HISTORICAL_MODELS = "HistoricalModels";
    private static final String COMPLETE_DESCRIPTION_KEY = "CompleteDescription";
    private static final String CERTIFICATION_REQUIRE_KEY = "CertificationRequire";

    @Resource
    private TyplmPartService typlmPartService;
    @Resource
    private CodeSequenceService codeSequenceService;
    @Resource
    private TyplmCommonSearchService typlmCommonSearchService;
    @Resource
    private RTClassificationMapper classificationMapper;
    @Resource
    private RTPartMapper rtPartMapper;
    @Resource
    private RTTypeClassMapper rtTypeClassMapper;
    @Resource
    private TyplmObjsRenameService typlmObjsRenameService;
    @Resource
    private TyplmLifecycleTemplateService typlmLifecycleTemplateService;
    @Resource
    private RTTypeClassMapper typeClassMapper;
    @Resource
    private RtCertBasecertMapper rtCertBaseCertMapper;
    @Resource
    private RTClassificationService classificationService;
    @Resource
    private MaterialCodeMapper materialCodeMapper;
    @Resource
    private CommonService commonService;


    /**
     * 创建零件时设置编码
     * @param proceedingJoinPoint
     * @return
     */
    @SneakyThrows
    @Around(value = "execution(* com.hustcad.plm.pdm.middle.partbom.service.TyplmPdmPartService.insertPart(..))")
    public Object checkWhenCreateChangeRequest(ProceedingJoinPoint proceedingJoinPoint) {
        log.info("切面==================");
        Object[] args = proceedingJoinPoint.getArgs();
        InsertPartDTO insertPartDto = (InsertPartDTO) args[2];

        String typeOType = insertPartDto.getTypeOType();
        LinkedHashMap<String, List<String>> ibaAttributeMap = insertPartDto.getIbaAttribute();
        if(ibaAttributeMap.containsKey("isSimilarCreate")){
            return proceedingJoinPoint.proceed();
        }
        dealInsertPartData(insertPartDto, typeOType, ibaAttributeMap);
        Object proceed = proceedingJoinPoint.proceed();
        PdmPartInfoVO pdmPartInfoVO = (PdmPartInfoVO) proceed;
        String typeotype = pdmPartInfoVO.getTypeotype();
        if("ty.inteplm.part.CTyPart|PatternCode".equals(typeotype)){
            dealMaterialCodeDescription(pdmPartInfoVO, insertPartDto);
        }
        return proceed;
    }

    private void dealInsertPartData(InsertPartDTO insertPartDto, String typeOType,
                           LinkedHashMap<String, List<String>> ibaAttributeMap) {
        if (log.isDebugEnabled()){
            log.debug("根据DTO有无Number识别是否来自“图号升级”===>{}",insertPartDto.getPartNumber());
        }
        // 是否来自图号升级标识
        boolean fromTHSJ = false;
        if (StringUtils.isNotBlank(insertPartDto.getPartNumber())){
            fromTHSJ = true;
        }
        BigInteger classId = insertPartDto.getClassId();

        List<String> list = Arrays.asList(PATTERN_CODE_TYPE, STANDARD_TYPE, EBOM_NUM_TYPE);
        if (list.contains(typeOType)) {
            DescriptionVO descriptionVO = getDescriptionVO(ibaAttributeMap, classId, typeOType, Boolean.FALSE);
            String description = descriptionVO.getIbaDescription();
            String completeDescription = descriptionVO.getSystemDescription();
            ibaAttributeMap.remove(DESCRIPTION_KEY);
            ibaAttributeMap.put(DESCRIPTION_KEY, Collections.singletonList(description));
            ibaAttributeMap.put(COMPLETE_DESCRIPTION_KEY, Collections.singletonList(completeDescription));
            insertPartDto.setDescription(completeDescription);
            // 检查描述是否重复
            if(fromTHSJ){
                checkDescriptionIsExist(completeDescription, insertPartDto.getPartNumber(), typeOType, Boolean.TRUE, Boolean.FALSE);
            } else {
                checkDescriptionIsExist(completeDescription, null, typeOType, Boolean.FALSE, Boolean.FALSE);
            }
            // 图样代号，升级按钮进来时不再生产描述
        } else if (MATERIAL_CODE_TYPE.equals(typeOType) && !fromTHSJ) {
            dealMaterialCodeDescription(ibaAttributeMap, classId, insertPartDto.getPartNumber());
        }

        //图样代号，升级按钮进来时不修改编码
        if(PATTERN_CODE_TYPE.equals(typeOType) && !fromTHSJ){
//            ClassificationDO classificationDO = getClassification(classId);
            String name =codeSequenceService.selectCategoryCodeByClassId(classId);
//            String name = extractClassCode(classificationDO.getName());

            setInsertPartDTOName(name, insertPartDto);
            CodeDrawingDO codeDrawingDO = new CodeDrawingDO();
            codeDrawingDO.setClassificationId(name);
            //设置开发令
            if(ibaAttributeMap.containsKey(DEV_CODE_KEY) && CollUtil.isNotEmpty(ibaAttributeMap.get(DEV_CODE_KEY)) && StringUtils.isNotEmpty(
                    ibaAttributeMap.get(DEV_CODE_KEY).get(0))){
                codeDrawingDO.setDevelopmentOrder(ibaAttributeMap.get(DEV_CODE_KEY).get(0));
            }else {
                throw RTErrorCodeEnum.GENERATE_CODE_ERROR.getException("开发令属性为空，请检查开发令");
            }
            //设置组合键属性
            if(ibaAttributeMap.containsKey("Combination") && CollUtil.isNotEmpty(ibaAttributeMap.get("Combination")) && "0".equals(
                    ibaAttributeMap.get("Combination").get(0))){
                codeDrawingDO.setRemark("-");
            }else {
                codeDrawingDO.setRemark("H");
            }

            //生成编码
            String drawingCode = codeSequenceService.generateDrawingCode(codeDrawingDO);
            insertPartDto.setPartNumber(drawingCode);
        } else if(MATERIAL_CODE_TYPE.equals(typeOType) && !fromTHSJ){
            //物料码
            CodeMaterialDO dto = new CodeMaterialDO();
            String patternCode = getAttributeValue(ibaAttributeMap, PATTERN_CODE_KEY);
            if(StringUtils.isNotEmpty(patternCode) && StringUtils.isNotBlank(patternCode)){
                setInsertPartDTOName(patternCode.substring(0,5), insertPartDto);
                dto.setDrawingCode(patternCode);
            }else {
                throw RTErrorCodeEnum.GENERATE_CODE_ERROR.getException("图样代号属性为空，请检查图样代号");
            }
            Map<String, String> colorMap = new LinkedHashMap<>();
            ibaAttributeMap.entrySet().stream().filter(entry -> entry.getKey().startsWith("color")).filter(entry -> CollUtil.isNotEmpty(entry.getValue()))
                    .forEach(entry -> {
                        String value = entry.getValue().get(0);
                        if (StringUtils.isNotBlank(value)) {
                            colorMap.put(entry.getKey(), value);
                        }
                    });

            if(colorMap.size()==1){
                List<String> values = new ArrayList<>(colorMap.values());
                String monochrome = values.get(0);
                dto.setMonochrome(monochrome);
            }else if(colorMap.size()>1) {
                List<Map.Entry<String, String>> sortedEntries = new ArrayList<>(colorMap.entrySet());
                sortedEntries.sort(Map.Entry.comparingByKey());
                StringBuilder sb = new StringBuilder();
                for (Map.Entry<String, String> entry : sortedEntries) {
                    sb.append(entry.getKey()).append(entry.getValue());
                }
                dto.setCompositeColorValue(String.valueOf(sb));
            } else {
                throw RTErrorCodeEnum.GENERATE_CODE_ERROR.getException("未获取到颜色属性");
            }

            String materialCode = codeSequenceService.generateMaterialCode(dto);
            insertPartDto.setPartNumber(materialCode);
        } else if(STANDARD_TYPE.equals(typeOType)){

//            ClassificationDO classificationDO = getClassification(classId);
            String classCode =codeSequenceService.selectCategoryCodeByClassId(classId);
//            String classCode = extractClassCode(classificationDO.getName());
            setInsertPartDTOName(classCode, insertPartDto);

            Map<String, String> standardAttributes = new HashMap<>();
            putFirstValueIfPresent(standardAttributes, ibaAttributeMap, "specification", "属性卡片未维护规格，请检查规格");
            putFirstValueIfPresent(standardAttributes, ibaAttributeMap, "screwPitch", "属性卡片未维护螺距，请检查螺距");
            putFirstValueIfPresent(standardAttributes, ibaAttributeMap, "performance", "属性卡片未维护性能，请检查性能");
            putFirstValueIfPresent(standardAttributes, ibaAttributeMap, "surfaceTreatment", "属性卡片未维护表面处理方式，请检查表面处理方式");
            putFirstValueIfPresent(standardAttributes, ibaAttributeMap, "hazardousSubstance", "属性卡片未维护有害物质，请检查有害物质");
            putFirstValueIfPresent(standardAttributes, ibaAttributeMap, "specialRequirement", "属性卡片未维护特殊要求，请检查特殊要求");

            String standardCode = codeSequenceService.generateStandardCode(classCode, standardAttributes);
            insertPartDto.setPartNumber(standardCode);

        } else if(EBOM_NUM_TYPE.equals(typeOType)){
            //生成EBOM号
            String devCode = getAttributeValue(ibaAttributeMap,DEV_CODE_KEY);
            List<PartMasterDO> partMasterDOS = typlmPartService.queryPartMasterByPartNumber(devCode);
            if(CollUtil.isNotEmpty(partMasterDOS)){
                insertPartDto.setName(partMasterDOS.get(0).getName());
            }
            if(StringUtils.isNotBlank(devCode.trim()) && StringUtils.isNotEmpty(devCode.trim())){
                String ebomCode = codeSequenceService.generateEBOMCode(devCode);
                insertPartDto.setPartNumber(ebomCode);
            }else {
                throw RTErrorCodeEnum.GENERATE_CODE_ERROR.getException("开发令属性为空，请检查开发令");
            }
        } else if(PRODUCT_SPECTRUM_TYPE.equals(typeOType)){
            JSONObject data = typeClassMapper.selectClassNameAndCodeByClassId(String.valueOf(classId));
            String lineName = data.getString("VALUE");
            String lineCode = data.getString("OBJECTNUMBER");
//            RTProductDevelopmentOrderDTO rtProductDevelopmentOrderDTO = new RTProductDevelopmentOrderDTO();
//            rtProductDevelopmentOrderDTO.setProductLineName(lineName);
//            rtProductDevelopmentOrderDTO.setProductLineCode(lineCode);
//            String devCode = classificationService.addDevelopmentOrder(rtProductDevelopmentOrderDTO);
            List<String> numberList = rtPartMapper.queryPartNumberByLineCode(lineCode + "%");
            List<String> strings = SequenceGenerator.getSequenceList();
            String devCode = "";
            for(String number : strings) {
                if("00".equals(number)){
                    continue;
                }
                if(!numberList.contains(lineCode + number)){
                    devCode = lineCode + number;
                    break;
                }
            }
//            String devCode = materialCodeMapper.getNextCode(lineCode);
            ibaAttributeMap.put(DEV_CODE_KEY, Collections.singletonList(devCode));
            ibaAttributeMap.put("ProductLineName", Collections.singletonList(lineName));
            ibaAttributeMap.put("ProductLineCoding", Collections.singletonList(lineCode));
//            String devCode = getAttributeValue(ibaAttributeMap, DEV_CODE_KEY);
            String name = generateProductSpectrumName(ibaAttributeMap);
            insertPartDto.setPartNumber(devCode);
            insertPartDto.setName(name);
            boolean b = classificationMapper.selectPartByTypeAndName(PRODUCT_SPECTRUM_TYPE, name,null);
            if(b){
                throw RTErrorCodeEnum.GENERATE_CODE_ERROR.getException("机型重复，请检查机型（历史机型）！");
            }
        }
        LifeCycleTemplateDO lifeCycleTemplateDO = typlmLifecycleTemplateService.queryLifecycleByName("润通通用生命周期模板");
        insertPartDto.setLifecycleTemplateID(lifeCycleTemplateDO.getOid());
        insertPartDto.setTemplate("润通通用生命周期模板");
        insertPartDto.setLifecycleTemplate("润通通用生命周期模板");
    }


    private DescriptionVO getDescriptionVO(LinkedHashMap<String, List<String>> ibaAttribute, BigInteger classId, String typeOType, boolean isMaterial) {
        Map<String, String> partIbaMap = new LinkedHashMap<>();
//        if (ibaAttribute != null) {
//            for (Map.Entry<String, List<String>> entry : ibaAttribute.entrySet()) {
//                if (entry.getKey() != null) {
//                    String value = "";
//                    if (entry.getValue() != null && !entry.getValue().isEmpty()) {
//                        value = entry.getValue().get(0);
//                    }
//                    partIbaMap.put(entry.getKey(), Collections);
//                }
//            }
//        }
        GenerateDescriptionRuleDto generateDescriptionDto = new GenerateDescriptionRuleDto();
        generateDescriptionDto.setClassId(String.valueOf(classId));
        generateDescriptionDto.setIbaMap(ibaAttribute);
        generateDescriptionDto.setIsMaterial(String.valueOf(isMaterial));
        generateDescriptionDto.setType(typeOType);
        return codeSequenceService.generateDescriptionRule(generateDescriptionDto, Boolean.FALSE);
    }

    private void setInsertPartDTOName(String name, InsertPartDTO insertPartDto) {
        List<JSONObject> objectList = classificationMapper.selectPartNameByClassCode(name);
        if(objectList.isEmpty()){
            throw RTErrorCodeEnum.CLASSIFICATION_TYPE_ERROR.getException("无法根据品类码:" + name + "在系统中获取品类");
        } else if(objectList.size() > 1){
            List<String> collect = objectList.stream().map(jsonObject -> jsonObject.getString("VALUE")).collect(
                    Collectors.toList());
            throw RTErrorCodeEnum.CLASSIFICATION_TYPE_ERROR.getException("根据品类码:" + name + "在系统中获取多个品类,分别是:"+collect);
        } else{
            insertPartDto.setName(objectList.get(0).getString("VALUE"));
        }
    }

    private void putFirstValueIfPresent(Map<String, String> map, Map<String, List<String>> ibaAttribute, String key, String errorMessage) {
        if (ibaAttribute.containsKey(key) && CollUtil.isNotEmpty(ibaAttribute.get(key))) {
            map.put(key, ibaAttribute.get(key).get(0));
        } else {
            throw RTErrorCodeEnum.GENERATE_CODE_ERROR.getException(errorMessage);
        }
    }

    /**
     * 修改零部件属性时，更新描述规则
     */
    @SneakyThrows
    @Around(value = "execution(* com.hustcad.plm.pdm.middle.partbom.service.impl.TyplmPdmPartServiceImpl.updatePart(..))")
    public Object updateClassificationParent(ProceedingJoinPoint point) {
        Object[] args = point.getArgs();
        ModifyPartDTO dto = (ModifyPartDTO)args[0];
        String partOid = dto.getOId();
        TyPartAllVO tyPartAllVO = typlmPartService.queryPartAllVO(new BigInteger(partOid), dto.getOType());
        String typeOid = String.valueOf(dto.getTypeOid());
        List<String> list = Arrays.asList(PATTERN_CODE_KEY, "Standard", "EBOM_NUM");
        String typeName = rtTypeClassMapper.queryTypeNameByOid(typeOid);
        String totalTypeName = TableTypeConstrant.TY_PART_OTYPE + "|" + typeName;
        LinkedHashMap<String, List<String>> ibaAttributeMap = dto.getIbaAttributeMap();
        IdentifierEntity entity = rtPartMapper.selectClassInfoByPartOid(dto.getOId());
        if (StringUtils.isNotEmpty(typeName) && list.contains(typeName)) {
            DescriptionVO descriptionVO = getDescriptionVO(ibaAttributeMap, entity.getOid(), totalTypeName, Boolean.FALSE);
            String description = descriptionVO.getIbaDescription();
            String systemDescription = descriptionVO.getSystemDescription();
            ibaAttributeMap.remove(DESCRIPTION_KEY);
            ibaAttributeMap.put(DESCRIPTION_KEY, Collections.singletonList(description));
            ibaAttributeMap.put(COMPLETE_DESCRIPTION_KEY, Collections.singletonList(systemDescription));
            dto.setDescription(systemDescription);
            if(PATTERN_CODE_KEY.equals(typeName)){
                checkDescriptionIsExist(systemDescription, tyPartAllVO.getObjectNumber().substring(0,11), totalTypeName, Boolean.TRUE, Boolean.FALSE);
            }else {
                checkDescriptionIsExist(systemDescription, tyPartAllVO.getObjectNumber(), totalTypeName, Boolean.FALSE, Boolean.FALSE);
            }

        } else if(RTPlmConstant.PARTTYPE.equalsIgnoreCase(typeName)){
            String name = generateProductSpectrumName(ibaAttributeMap);
            dto.setName(name);
            boolean b = classificationMapper.selectPartByTypeAndName(PRODUCT_SPECTRUM_TYPE, name,partOid);
            if(b){
                throw RTErrorCodeEnum.GENERATE_CODE_ERROR.getException("机型重复，请检查机型（历史机型）！");
            }
        } else if("MaterialCode".equals(typeName)){
            dealMaterialCodeDescription(ibaAttributeMap, entity.getOid(), tyPartAllVO.getObjectNumber());
        }
        return point.proceed();
    }

    /**
     * 生成产品型谱名称
     */
    private String generateProductSpectrumName(LinkedHashMap<String, List<String>> ibaAttribute) {
        StringBuilder name = new StringBuilder();

//        String devCode = getAttributeValue(ibaAttribute, DEV_CODE_KEY);
//        if (StringUtils.isNotBlank(devCode)) {
//            name.append(devCode);
//        }

        String productType = getAttributeValue(ibaAttribute, PRODUCT_TYPE_KEY);
        if (StringUtils.isNotBlank(productType)) {
            name.append(productType);
        }

        String historicalModels = getAttributeValue(ibaAttribute, HISTORICAL_MODELS);
        if (StringUtils.isNotBlank(historicalModels)) {
            name.append("(").append(historicalModels).append(")");
        }
        return String.valueOf(name);
    }

    /**
     * 处理专用件描述
     */
    private void dealMaterialCodeDescription(LinkedHashMap<String, List<String>> ibaAttribute,
                                            BigInteger classId, String partNumber) {
        DescriptionVO descriptionVO = getDescriptionVO(ibaAttribute, classId, MATERIAL_CODE_TYPE,Boolean.TRUE);

        // 获取图样代号描述
        String drawingCodeTotalDescription = getAttributeValue(ibaAttribute, "Common_Attributes|1757215074349");
        String drawingCodeSplitDescription = getAttributeValue(ibaAttribute, PATTERN_CODE_DESCRIPTION_KEY);

        // 构建物料码描述
        String materialCodeTotalDescription = descriptionVO.getSystemDescription();
        String materialCodeSplitDescription = descriptionVO.getIbaDescription();

        if (StringUtils.isNotBlank(drawingCodeTotalDescription)) {
            materialCodeTotalDescription =  drawingCodeSplitDescription+ ";" + materialCodeTotalDescription;
        }
        if (StringUtils.isNotBlank(drawingCodeSplitDescription)) {
            materialCodeSplitDescription = drawingCodeSplitDescription + ";" + materialCodeSplitDescription;
        }

        // 设置描述属性
        ibaAttribute.put(MATERIAL_CODE_DESCRIPTION_KEY, Collections.singletonList(materialCodeTotalDescription));
        ibaAttribute.put(DESCRIPTION_KEY, Collections.singletonList(materialCodeSplitDescription));
        if(StringUtils.isNotBlank(partNumber) && StringUtils.isNotEmpty(partNumber)){
            checkDescriptionIsExist(materialCodeTotalDescription, partNumber.substring(0,11), MATERIAL_CODE_TYPE, Boolean.FALSE, Boolean.TRUE);
        }

    }

    private void checkDescriptionIsExist(String materialCodeTotalDescription, String partNumber, String typeOType, boolean isDrawingCode, boolean isMaterialCode) {
        List<String> partNumberList = new ArrayList<>();
        // 检查描述是否重复
        if (isMaterialCode) {
            partNumberList = codeSequenceService.checkCurrentDescriptionIfExist(RTPlmConstant.IBA_MATERIALCODEDESCRIPTION , String.valueOf(materialCodeTotalDescription), typeOType);
        } else {
            //高级查询 检查是否存在相同描述属性物料
            partNumberList = codeSequenceService.checkCurrentDescriptionIfExist(RTPlmConstant.IBA_COMPLETEDESCRIPTION , String.valueOf(materialCodeTotalDescription), typeOType);
        }
        if (CollUtil.isNotEmpty(partNumberList)) {
            if(StringUtils.isNotEmpty(partNumber)&& StringUtils.isNotBlank(partNumber)){
                if("ty.inteplm.part.CTyPart|PatternCode".equals(typeOType)){
                    partNumber = partNumber.substring(0,partNumber.length()-2);
                }
                String finalPartNumber = partNumber;
                String partNumbers = partNumberList.stream().filter(item -> !item.startsWith(finalPartNumber)).collect(
                        Collectors.joining(","));
                if(StringUtils.isNotEmpty(partNumbers) && StringUtils.isNotEmpty(partNumbers)){
                    throw RTErrorCodeEnum.DESCRIBE_RULE_ERROR.getException(
                            "描述生成失败，该描述:"+ materialCodeTotalDescription +",与编码为:" + partNumbers + "的零部件描述一致");
                }
            }else {
                throw RTErrorCodeEnum.DESCRIBE_RULE_ERROR.getException(
                        "描述生成失败，该描述:"+ materialCodeTotalDescription +",与编码为:" + partNumberList + "的零部件描述一致");
            }
        }
    }

    private String getAttributeValue(LinkedHashMap<String, List<String>> ibaAttribute, String key){
        return ibaAttribute.containsKey(key) && CollUtil.isNotEmpty(ibaAttribute.get(key)) ? ibaAttribute.get(key).get(0) : "";
    }

    /**
     * EBOM检查认证信息
     */
    private void checkEbomCertificationInfo(LinkedHashMap<String, List<String>> ibaAttribute) {
        if(ibaAttribute.containsKey(CERTIFICATION_REQUIRE_KEY)){
            List<String> values = ibaAttribute.get(CERTIFICATION_REQUIRE_KEY);
            if(CollUtil.isNotEmpty(values)){
                String value = values.get(0);
                if("无认证".equals(value)){
                } else {
                    String[] certInfo = value.split(";;;");
                    List<RtCertBaseCertDO> certList = rtCertBaseCertMapper.queryCertByName(Arrays.asList(certInfo));
                    if(CollUtil.isNotEmpty(certList)){
                        if(!(ibaAttribute.containsKey("customerModel") && CollUtil.isNotEmpty(ibaAttribute.get("customerModel")) && StringUtils.isNotEmpty(ibaAttribute.get("customerModel").get(0)))){
                            throw RTErrorCodeEnum.CERT_NAME_EXISTS.getException("客户备案机型属性无值，请检查属性");
                        }
                    }
                }
            }
        }
    }

    /**
     * 类似创建增加编码等数据处理
     * @param point
     * @return
     * @throws Throwable
     */
    @Around(value = "execution(* com.hustcad.plm.pdm.partbom.service.TyplmPartBomService.similarCreate(..))")
    public Object similarCreateAop(ProceedingJoinPoint point) throws Throwable {
        Object[] args = point.getArgs();
        SimilarCreateDTO dto = (SimilarCreateDTO)args[0];
        InsertPartDTO insertPartDTO = dto.getInsertPartDTO();
        String typeName = typeClassMapper.queryTypeNameByOid(insertPartDTO.getTypeOid());
        dealInsertPartData(insertPartDTO, TableTypeConstrant.TY_PART_OTYPE + "|" + typeName, insertPartDTO.getIbaAttribute());
        return point.proceed();
    }


//    /**
//     * 删除物料
//     * @param point
//     * @return
//     * @throws Throwable
//     */
//    @Around(value = "execution(* com.hustcad.plm.pdm.partbom.service.impl.TyplmPartDeleteServiceImpl.deleteParts(..))")
//    public Object deleteParts(ProceedingJoinPoint point) throws Throwable {
//        Object[] args = point.getArgs();
//        List<String> partIDs = (List<String>)args[0];
//        String deleteRange = (String)args[1];
//        List<BigInteger> partOid = new ArrayList<>();
//        for(String partID : partIDs){
//            partOid.add(new BigInteger(partID));
//        }
//        List<TyPartAllVO> TyPartAllVOList = typlmPartService.queryPartAllVOList(partOid);
//        for(TyPartAllVO vo : TyPartAllVOList){
//            String typeName = vo.getTypeName();
//            if("ProductSpectrum".equals(typeName) && "allRevisions".equals(deleteRange)){
//                try {
//                    materialCodeMapper.releaseCode(vo.getObjectNumber());
//                }catch (Exception e){
//                    log.error("产品型谱: 【{}】 ,在数据库表中不存在", vo.getObjectNumber());
//                }
//            }
//        }
//        return point.proceed();
//    }


    private static final String MATERIAL_TYPE = "ty.inteplm.part.CTyPart|MaterialCode";

    @Resource
    private TyplmAttributeValueService typlmAttributeValueService;
    @Resource
    private RTAttributeCardService rtAttributeCardService;
    @Resource
    private TyplmTypeService typlmTypeService;
    @Resource
    private TyplmDefaultValueService typlmDefaultValueService;
    @Resource
    private TyplmPdmPartService typlmPdmPartService;
    @Resource
    private ObjectStorageService objectStorageService;
    @Resource
    private StoragePlanningMapper storagePlanningMapper;
    @Resource
    private TyplmSubFolderLinkService typlmSubFolderLinkService;

    private void dealMaterialCodeDescription(PdmPartInfoVO pdmPartInfoVO, InsertPartDTO insertPartDto) {
        BigInteger typeOid = rtTypeClassMapper.queryTypeOidByName(MATERIAL_TYPE);
        Map<String, List<String>> ibaAttribute = insertPartDto.getIbaAttribute();
        List<String> strings = ibaAttribute.get("IsGenerateMaterialCode");
        if(CollUtil.isNotEmpty(strings)){
            if ("1".equals(strings.get(0))) {
                String patternCode = pdmPartInfoVO.getPartNumber();
                FlexibleMatchDTO dto = new FlexibleMatchDTO();
                dto.setPatternCode(patternCode);
                dto.setType("物料码");
                ClassificationDTO classificationD0 = rtAttributeCardService.flexibleMatch(dto);
                if (ObjectUtils.isNotEmpty(classificationD0)) {
//                    List<TyAttributeDefMapVO> attrDefMapList = this.typlmTypeService.queryInheritAttrDef(
//                            classificationD0.getOid(), classificationD0.getOtype());
                    LinkedHashMap<String, List<String>> ibaAttrMap = new LinkedHashMap<>();
//                    for (TyAttributeDefMapVO tyAttributeDefMapVO : attrDefMapList) {
//                        Map<String, TyplmDefaultValueParamDTO> map = new HashMap<>();
//                        TyplmDefaultValueParamDTO typlmDefaultValueParamDTO = new TyplmDefaultValueParamDTO();
//                        typlmDefaultValueParamDTO.setEntity(new IdentifierEntity(tyAttributeDefMapVO.getOid(),tyAttributeDefMapVO.getOtype()));
//                        map.put(TableTypeConstrant.TY_CLASSIFICATION_OTYPE + ":" + classificationD0.getOid(), typlmDefaultValueParamDTO);
//                        Map<String, List<TyplmAttrDefaultValueDTO>> entityDefaultValueList = typlmDefaultValueService.getEntityDefaultValueList(map);
//                        //查询默认值
//                        List<String> defaultValues = entityDefaultValueList.values().stream()
//                                .flatMap(List::stream)
//                                .map(TyplmAttrDefaultValueDTO::getDefaultValue)
//                                .filter(Objects::nonNull)
//                                .collect(Collectors.toList());
//                        ibaAttrMap.put(tyAttributeDefMapVO.getName(), defaultValues);
//                    }
                    ibaAttrMap.put("PatternCode", Collections.singletonList(patternCode));
                    InsertPartDTO insertPartDTO = new InsertPartDTO();
                    for(Map.Entry<String,List<String>> entry : ibaAttribute.entrySet()) {
                        String key = entry.getKey();
                        if(ibaAttrMap.containsKey(key)){
                            List<String> strings1 = ibaAttribute.get(key);
                            if(CollUtil.isNotEmpty(strings1)){
                                continue;
                            }
                        }
                        List<String> value1 = entry.getValue();
                        if ("CompleteDescription".equals(key)) {
                            // 图样代号完整描述
                            ibaAttrMap.put("Common_Attributes|1757215074349", value1 );
                        } else if ("Description".equals(key)) {
                            // 图样代号拼接描述
                            ibaAttrMap.put("PatternCodeDescription", value1 );
                        }else {
                            ibaAttrMap.put(key, value1);
                        }
                    }
                    GenerateDescriptionRuleDto generateDescriptionRuleDto = new GenerateDescriptionRuleDto();
                    generateDescriptionRuleDto.setClassId(classificationD0.getOid().toString());
                    generateDescriptionRuleDto.setIbaMap(ibaAttrMap);
                    generateDescriptionRuleDto.setIsMaterial("true");
                    generateDescriptionRuleDto.setType("MaterialCode");
                    DescriptionVO descriptionVO = codeSequenceService.generateDescriptionRule(generateDescriptionRuleDto,
                                                                                              Boolean.TRUE);
                    // 获取图样代号描述
                    String drawingCodeTotalDescription = getAttributeValue(ibaAttrMap, "Common_Attributes|1757215074349");
                    String drawingCodeSplitDescription = getAttributeValue(ibaAttrMap, "PatternCodeDescription");

                    // 构建物料码描述
                    String materialCodeTotalDescription = descriptionVO.getSystemDescription();
                    String materialCodeSplitDescription = descriptionVO.getIbaDescription();

                    if (StringUtils.isNotBlank(drawingCodeTotalDescription)) {
                        materialCodeTotalDescription = drawingCodeSplitDescription + ";" + materialCodeTotalDescription;
                    }
                    if (StringUtils.isNotBlank(drawingCodeSplitDescription)) {
                        materialCodeSplitDescription = drawingCodeSplitDescription + ";" + materialCodeSplitDescription;
                    }

                    // 设置描述属性
                    ibaAttrMap.put("MaterialCodeDescription", Collections.singletonList(materialCodeTotalDescription));
                    ibaAttrMap.put("Description", Collections.singletonList(materialCodeSplitDescription));
                    insertPartDTO.setIbaAttribute(ibaAttrMap);
                    insertPartDTO.setTypeOid(String.valueOf(typeOid));
                    insertPartDTO.setClassId(classificationD0.getOid());
                    insertPartDTO.setTypeOType(MATERIAL_TYPE);
                    insertPartDTO.setPartView(pdmPartInfoVO.getView());
                    insertPartDTO.setName(pdmPartInfoVO.getName());
                    insertPartDTO.setEnditem(0L);
                    insertPartDTO.setLifecycleState("Creating");
                    //----------------------------------------------------------------------
                    ObjectStorageDO objectStorageDO = objectStorageService.selectOneByTypeDefName("物料码");
                    if (objectStorageDO != null) {
                        PDFProjectVO v = storagePlanningMapper.selectPdmIds(objectStorageDO.getContextName());
                        String[] split = objectStorageDO.getFolderPath().split("/");
                        String folderId = null;
                        if (objectStorageDO != null) {
                            for (int i = 0; i < split.length; i++) {
                                String id = null;
                                if (StrUtil.isBlank(split[i])) {
                                    continue;
                                }
                                if (i == 1) {
                                    id = storagePlanningMapper.selectOidByNameAndCid(v.getOId(),
                                                                                     split[i], "0");
                                    if (StrUtil.isNotBlank(id)) {
                                        folderId = id;
                                    }
                                } else {
                                    id = storagePlanningMapper.selectOidByNameAndCid(v.getOId(), split[i], folderId);
                                    if (StrUtil.isNotBlank(id)) {
                                        folderId = storagePlanningMapper.selectOidByNameAndCid(v.getOId(),
                                                                                               split[i], folderId);
                                    }

                                }
                                if (StrUtil.isBlank(id)) {
                                    //创建文件夹
                                    SubfolderVO subfolder = new SubfolderVO();
                                    subfolder.setName(split[i]);
                                    subfolder.setDescription("--系统自动创建--文件夹--");
                                    subfolder.setParentOid(i == 1 ? v.getDefaultcabinetoid() : folderId);
                                    subfolder.setParentOtype(
                                            i == 1 ? "ty.inteplm.folder.CTyCabinet" : "ty.inteplm.folder.CTySubFolder");
                                    SubfolderWebVO subfolderWebVO = typlmSubFolderLinkService.createSubfolder(subfolder);
                                    folderId = subfolderWebVO.getOid();
                                }
                            }
                            insertPartDTO.setFolderId(folderId);
                            insertPartDTO.setContainerID(v.getOId());
                            insertPartDTO.setFolderPath(objectStorageDO.getFolderPath());
                            insertPartDTO.setContainerName(objectStorageDO.getContextName());
                            insertPartDTO.setContainerType("ty.inteplm.product.CTyPDMLinkProduct");
                            insertPartDTO.setProductID(v.getOId());
                        }
                    }
                    //------------------------------------------------------------------------
                    typlmPdmPartService.insertPart(new UploadFileDTO(), new LinkedHashMap<>(),
                                                   insertPartDTO);
                }
            }
        }
    }

}